package com.yzmoney.wechat.service;

import com.yzmoney.common.constant.Constants;
import com.yzmoney.common.constant.PropertyUtils;
import com.yzmoney.common.util.HttpClientUtil;
import com.yzmoney.common.util.JDKStackTrace;
import com.yzmoney.common.util.JsonUtils;
import com.yzmoney.wechat.model.token.AuthAccessTokenJson;
import com.yzmoney.wechat.model.token.AuthUserInfoJson;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * <p/>
 * 1.网页通过访问微信授权页面用户授权后将请求一个回调页面，其中携带code参数 2.通过code参数，请求获取网页鉴权access_token(会过期)
 * , openId ,refresh_access_token 3.refresh_access_token 获取新的
 * 鉴权access_token(非必要) 4.通过鉴权access_token + openId 获取到的信息
 * headerUrl、openId、nickname (这里的获取用户信息与关注微信公众号后获取用户信息的请求地址不一样) *
 *
 * @author DOVE
 */
@Component
public class WechatOAuthService {
    private static Logger logger = Logger.getLogger(WechatOAuthService.class);

    private static String gzhBaseOAuthUrl = PropertyUtils.getValue("oAuthUrl",
            "", Constants.GZH_PATH);

    private static String gzhBaseOAuthUserInfoUrl = PropertyUtils.getValue(
            "AUTHUSERINFOURL", "", Constants.GZH_PATH);

	private static String appid = PropertyUtils.getValue("APPID", "",
			Constants.GZH_PATH);

	private static String appsecret = PropertyUtils.getValue("APPSECRET", "",
			Constants.GZH_PATH);


    public WechatOAuthService() {
        super();
    }

	/*
	 * 通过code 获取用户信息
	 * 
	 * @param code
	 * @return
	 */
	public AuthUserInfoJson loadWechatUserInfo(String code) {
		try {
			String authUrl = getGZHOauthUrl(code);
			String replyJsonStr = HttpClientUtil.get(authUrl,null,null);
			logger.info("authUrl:"+authUrl+",code:"+code+",replyJsonStr:"+replyJsonStr);
			AuthAccessTokenJson authAccessTokenJson = JsonUtils.toObject(
					replyJsonStr, AuthAccessTokenJson.class);
			if (authAccessTokenJson != null) {
				String authUserUrl = getGZHOauthUserInfoUrl(
						authAccessTokenJson.getAccess_token(),
						authAccessTokenJson.getOpenid());
				String authUserReplyStr = HttpClientUtil
						.get(authUserUrl, null, null);
				logger.info(Constants.LOGPRIFIX + "authUserReplyStr="
						+ authUserReplyStr);
				JSONObject object = JSONObject.fromObject(authUserReplyStr);
				AuthUserInfoJson userInfo = new AuthUserInfoJson(object.getString("openid"),
													object.getString("nickname"),
													object.getString("headimgurl"),
													object.getString("unionid"));
				return userInfo;
			}
		} catch (Exception e) {
			logger.warn("code:" + code + JDKStackTrace.getJDKStrack(e));
		}
		return null;
	}

    /**
     * 获取 auth 2.0 Access_token
     *
     * @param code
     * @return
     */
    public AuthAccessTokenJson loadAccessToken(String code) {
        try {
            String oAuthUrl = getGZHOauthUrl(code);
            String replyJsonStr = HttpClientUtil.get(oAuthUrl, null, null);
            logger.info(Constants.LOGPRIFIX + "replyJsonStr=" + replyJsonStr);
            AuthAccessTokenJson authAccessTokenJson = null;
            if (!StringUtils.isEmpty(replyJsonStr)) {
                authAccessTokenJson = JsonUtils.toObject(replyJsonStr,
                        AuthAccessTokenJson.class);
            }
            return authAccessTokenJson;
        } catch (Exception e) {
            logger.warn("通过code:" + code + ",获取用户信息错误"
                    + JDKStackTrace.getJDKStrack(e));
        }
        return null;
    }

    /**
     * 获取 auth 2.0 微信用户信息
     *
     * @param authAccessTokenJson
     * @return
     */
    public AuthUserInfoJson loadUserInfo(AuthAccessTokenJson authAccessTokenJson) {
        try {
            if (authAccessTokenJson != null) {
                String authUserUrl = getGZHOauthUserInfoUrl(
                        authAccessTokenJson.getAccess_token(),
                        authAccessTokenJson.getOpenid());
                String authUserReplyStr = HttpClientUtil
                        .get(authUserUrl, null, null);
                logger.info(Constants.LOGPRIFIX + "authUserReplyStr="
                        + authUserReplyStr);
                JSONObject jsonObject = JSONObject.fromObject(authUserReplyStr);
                String openid = (String) jsonObject.get("openid");
                String nickname = (String) jsonObject.get("nickname");
                String headimgurl = (String) jsonObject.get("headimgurl");
                String unionId = (String) jsonObject.get("unionid");
                if (StringUtils.isNotEmpty(openid)) {
                    AuthUserInfoJson userInfo = new AuthUserInfoJson(openid,
                            nickname, headimgurl, unionId);
                    return userInfo;
                }
            }
        } catch (Exception e) {
            logger.warn("通过authAccessTokenJson:"
                    + JsonUtils.toJson(authAccessTokenJson) + ",获取用户信息错误"
                    + JDKStackTrace.getJDKStrack(e));
        }
        return null;
    }

    public AuthUserInfoJson loadUserInfo(String openId, String authAccessToken) {
        try {
            if (StringUtils.isNoneEmpty(openId)
                    && StringUtils.isNotEmpty(authAccessToken)) {
                String oAuthUserUrl = getGZHOauthUserInfoUrl(authAccessToken,
                        openId);
                String authUserReplyStr = HttpClientUtil
                        .get(oAuthUserUrl, null, null);
                logger.info(Constants.LOGPRIFIX + "authUserReplyStr="
                        + authUserReplyStr);
                JSONObject jsonObject = JSONObject.fromObject(authUserReplyStr);
                String openid = (String) jsonObject.get("openid");
                String nickname = (String) jsonObject.get("nickname");
                String headimgurl = (String) jsonObject.get("headimgurl");
                String unionId = (String) jsonObject.get("unionid");
                if (StringUtils.isNotEmpty(openid)) {
                    AuthUserInfoJson userInfo = new AuthUserInfoJson(openid,
                            nickname, headimgurl, unionId);
                    return userInfo;
                }
            }
        } catch (Exception e) {
            logger.warn("通过openId: " + openId + ",authAccessToken:"
                    + authAccessToken + ",获取用户信息错误"
                    + JDKStackTrace.getJDKStrack(e));
        }
        return null;
    }

    /**
     * 获取 auth 2.0 Access_token
     *
     * @param code
     * @return
     */
    public AuthAccessTokenJson loadAccessToken(String code, String appId,
                                               String appsecret) {
        try {
            String authUrl = getOpenOauthUserInfoUrl(code, appId, appsecret);
            String replyJsonStr = HttpClientUtil.get(authUrl, null, null);
            logger.info(Constants.LOGPRIFIX + ",authUrl:" + authUrl + "replyJsonStr=" + replyJsonStr);
            if (replyJsonStr.indexOf("errcode") != -1) {
                return null;
            }
            AuthAccessTokenJson authAccessTokenJson = JsonUtils.toObject(
                    replyJsonStr, AuthAccessTokenJson.class);
            return authAccessTokenJson;

        } catch (Exception e) {
            logger.warn("通过code: " + code + ",获取AuthAccessTokenJson"
                    + JDKStackTrace.getJDKStrack(e));
        }
        return null;
    }

    public boolean load() {
        return true;
    }

    public boolean refreshAccessToken() {
        return true;
    }

    /**
     * 拼接公众号 OAuth2.0请求地址
     *
     * @return
     */
    private static String getGZHOauthUrl(String code) {
        String oAuthUrl = gzhBaseOAuthUrl + "?appId=" + appid + "&secret="
                + appsecret + "&code=" + code
                + "&grant_type=authorization_code";
        return oAuthUrl;
    }

    /**
     * 拼接公众号 OAuth2.0 请求地址 根据Code 获取openId
     *
     * @return
     */
    private static String getOpenOauthUserInfoUrl(String code, String appid, String appsecret) {
        String oAuthUrl = gzhBaseOAuthUrl + "?appId=" + appid + "&secret="
                + appsecret + "&code=" + code
                + "&grant_type=authorization_code";
        return oAuthUrl;
    }

    /**
     * 拼接公众号 OAuth2.0 获取userInfo请求地址
     *
     * @return
     */
    private static String getGZHOauthUserInfoUrl(String access_Token,
                                                 String openId) {
        String oAuthUrl = gzhBaseOAuthUserInfoUrl + "?access_token="
                + access_Token + "&openid=" + openId + "&lang=zh_CN";
        return oAuthUrl;
    }
}
